package org.bootstrap.service.Impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import lombok.Getter;
import org.bootstrap.service.FileService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

@Service
@Lazy
@PropertySource("classpath:application.yml")
public class FileServiceImpl implements FileService {

    @Value("${local-disk.root}")
    private String root;
    @Value("${img-avg}")
    private String imgAvg;
    @Resource
    private UserServiceImpl userService;
    @Getter
    @Value("${local-disk.uri}")
    private String uri;
    @Value("${local-disk.img_common}")
    private String imgCommon;

    @PostConstruct
    public void init() {
        if (!FileUtil.exist(root)) {// 初始化目录
            FileUtil.mkdir(root);
        }
        if (!FileUtil.exist(root + "\\" + imgAvg)) {
            FileUtil.mkdir(root + "\\" + imgAvg);
            FileUtil.mkdir(root + "\\" + imgCommon);
        }
    }

    @Override
    public boolean user_avg_modify(MultipartFile[] file_list, String token) {
        AtomicBoolean success = new AtomicBoolean(false);
        if (StrUtil.isNotEmpty(token)) {
            JSONObject veritied = userService.verity_token_width_db(token, true);
            if (!veritied.isEmpty() && BooleanUtil.isTrue(veritied.getBool("success"))) {// 验证通过
                whiteImageToDisk(file_list, root + "\\" + imgAvg, (list) -> {
                    if (StrUtil.isNotEmpty(veritied.getStr("user_id"))) {
                        list.forEach(path -> {
                            success.set(userService.update_avg(veritied.getStr("user_id"), uri + "/image/" + path));
                        });
                    }
                });
            } else {
                Console.error("验证不通过", veritied);// 验证不通过
            }
        }
        return success.get();
    }

    /*
     * @author 写入图片并返回随机名字
     * @param file_list 文件list
     * @param path 存储路径
     * @return 文件名字列表
     */
    public void whiteImageToDisk(MultipartFile[] file_list, String path, Consumer<ArrayList<String>> t) {
        if (Objects.isNull(file_list) || file_list.length == 0) {
            return;
        }
        ArrayList<String> fileNameList = new ArrayList<>();
        for (MultipartFile file : file_list) { // 写入磁盘
            String suffix = FileUtil.getSuffix(file.getOriginalFilename());
            try {
                String name = RandomUtil.randomString(12) + "." + suffix;
                file.transferTo(FileUtil.file(path + "\\" + name));
                fileNameList.add(name);
            } catch (IOException e) {
                Console.error(e.getMessage());
            }
        }
        if (Objects.nonNull(t)) {
            t.accept(fileNameList);
        }
    }

    @SuppressWarnings("all")
    public @ResponseBody byte[] loadImage(String id,String dir) {
        if (StrUtil.isNotEmpty(id)) {
            String path = root + "\\" + dir + "\\" + id;
            File file = FileUtil.file(path);
            if (file.exists() && file.canRead()) {
                try (FileInputStream fin = new FileInputStream(file)) {
                    byte[] bytes = new byte[fin.available()];
                    fin.read(bytes, 0, fin.available());
                    return bytes;
                } catch (Exception ignore) {
                    return null;
                }
            } else {
                return null;
            }
        } else {
            return null;
        }
    }
}
